package com.atwy.utils;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.swetake.util.Qrcode;
import net.coobird.thumbnailator.Thumbnailator;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

/**
 * @Author: 30467
 * @Date: 2020/5/18
 */
public class IOUtils {

    public static final String PATH = "D:\\BB\\";
    /**
     * 分割文件夹目录
     *
     * @param str
     * @return
     */
    public static String getSavePath(String str) {
        String path = String.valueOf(str);
        char[] chrCharArray;
        chrCharArray = path.toCharArray();
        path = "";
        for (int i = 0; i < chrCharArray.length; i++) {
            path += chrCharArray[i];
            if ((i + 1) % 2 == 0 && (i + 1) != chrCharArray.length) {
                path += "/";
            }
        }
        return path;
    }


    /**
     * 获得图片二进制流
     * 若要转string
     * static BASE64Encoder encoder = new sun.misc.BASE64Encoder();
     * return encoder.encodeBuffer(bytes).trim();
     */
    public static byte[] getImageBinary(String Imgpath) {
        File f = new File(Imgpath);
        BufferedImage bi;
        try {
            bi = ImageIO.read(f);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bi, "jpg", baos);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据二进制保存图片
     *
     * @param bytes1
     * @param zpurl
     */
    public static void saveZp(byte[] bytes1, String zpurl) {
        try {
            File dir = new File(zpurl.substring(0, zpurl.lastIndexOf(File.separator)));
            // 判断文件夹是否生成
            if (!dir.exists()) {
                dir.mkdirs();
            }
            // 生成新文件
            File newFile = new File(zpurl);
            // 是否存在
            if (!newFile.exists()) {
                newFile.createNewFile();
            }
            // 指定输出流文件
            FileOutputStream out = new FileOutputStream(newFile);
            out.write(bytes1);
            // 关闭输入，输出流
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 生成二维码
     *
     * @param content 二维码内容
     * @param size    设置设置二维码尺寸，取值范围1-40，值越大尺寸越大，可存储的信息越大
     */
    public static byte[] getEwm(String content, int size) {
        try {
            Qrcode handler = new Qrcode();
            // 设置二维码排错率，可选L(7%)、M(15%)、Q(25%)、H(30%)，排错率越高可存储的信息越少，但
            handler.setQrcodeErrorCorrect('M');
            handler.setQrcodeEncodeMode('B');
            // 设置设置二维码尺寸，取值范围1-40，值越大尺寸越大，可存储的信息越大
            handler.setQrcodeVersion(size);

            // 获得内容的字节数组，设置编码格式
            byte[] contentBytes = content.getBytes("UTF-8");

            // 图片尺寸
            int imgSize = 67 + 12 * (size - 1);

            BufferedImage bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);

            Graphics2D gs = bufImg.createGraphics();

            // 设置背景颜色
            gs.setBackground(Color.WHITE);
            gs.clearRect(0, 0, imgSize, imgSize);

            //设定图像颜色：BLACK
            gs.setColor(Color.BLACK);

            //设置偏移量  不设置可能导致解析出错
            int pixoff = 2;
            //输出内容：二维码
            if (contentBytes.length > 0 && contentBytes.length < 800) {
                boolean[][] codeOut = handler.calQrcode(contentBytes);
                for (int i = 0; i < codeOut.length; i++) {
                    for (int j = 0; j < codeOut.length; j++) {
                        if (codeOut[j][i]) {
                            gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
                        }
                    }
                }
            } else {
                System.err.println("QRCode content bytes length = " + contentBytes.length + " not in [ 0,800 ]. ");
            }

            gs.dispose();
            bufImg.flush();
            ByteArrayOutputStream bot = new ByteArrayOutputStream();
            ImageIO.write(bufImg, "png", bot);
            byte[] b = null;
            b = bot.toByteArray();
            return b;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 生成文字图片覆盖在 oldimg上
     *
     * @param words      需要生产的文字
     * @param wordspath  文字保存路径
     * @param i          文字编号
     * @param color      文字颜色
     * @param wordscount 每行文字数量
     * @param font       字体
     */
    public static void creatWordsImg(String words, String wordspath, int i, Color color, int wordscount, Font font) {

        int fontsize = font.getSize();
        int width = 0;
        if (words.length() <= 1) {
            width = 300;
        } else {
            width = (int) Math.round((fontsize + 2) * wordscount * 3);
        }

        int height = ((words.length() / wordscount) + 1) * (fontsize) + 100;


        // 创建BufferedImage对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取Graphics2D
        Graphics2D g2d = image.createGraphics();
        // ---------- 增加下面的代码使得背景透明 -----------------
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = image.createGraphics();
        // ---------- 背景透明代码结束 -----------------

        // 画图
        g2d.setColor(color);
        g2d.setFont(font);
        g2d.setStroke(new BasicStroke(100));


        if (words.length() > wordscount) {
            //文字总长度
            Double textLineCount = Math.ceil(words.length() / wordscount);
            // 实际所有的水印文字的高度
            int textHeight = textLineCount.intValue() * fontsize;
            // 相对与X的起始的位置
            int originX = 0;
            // 相对与Y的起始的位置
            int originY = fontsize + 20;
            // 实际文字大于1行，则x则为默认起始0，
            // 实际文字行数大于1，1/2个图片高度减去文字行数所需的高度
            originY = (height - textHeight) / 2;

            //文字叠加,自动换行叠加
            int tempX = originX;
            int tempY = originY;
            int tempCharLen = 0;//单字符长度
            int tempLineLen = 0;//单行字符总长度临时计算
            StringBuffer stringBuffer = new StringBuffer();
            for (int k = 0; k < words.length(); k++) {
                char tempChar = words.charAt(k);
                tempCharLen = g2d.getFontMetrics(g2d.getFont()).charWidth(tempChar);
                if (tempLineLen >= wordscount * fontsize) {
                    // 绘制前一行
                    g2d.drawString(stringBuffer.toString(), tempX, tempY);
                    //清空内容,重新追加
                    stringBuffer.delete(0, stringBuffer.length());
                    //文字长度已经满一行,Y的位置加1字符高度
                    tempY = tempY + fontsize + 2;
                    tempLineLen = 0;
                }
                //追加字符
                stringBuffer.append(tempChar);
                tempLineLen += tempCharLen;
            }
            //最后叠加余下的文字
            g2d.drawString(stringBuffer.toString(), tempX, tempY);
        } else {
            g2d.drawString(words, 0, fontsize + 20);
        }

        //释放对象
        g2d.dispose();
        // 保存文件
        try {
            File file = new File(wordspath);
            if (!file.exists()) {
                file.mkdirs();
            }
            ImageIO.write(image, "png", new File(wordspath + "/words" + i + ".png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    /**
     * 把图片印刷到图片上
     *
     * @param  --
     *                  水印文件
     * @param targetImg --
     *                  目标文件
     * @param          --x坐标
     * @param         --y坐标
     * @throws IOException
     */
    public static void pressImage(String targetImg, List<Imageftl> list, String wordspath) {
        try {
            //目标文件
            File _file = new File(targetImg);
            Image src = ImageIO.read(_file);
            int wideth = src.getWidth(null);
            int height = src.getHeight(null);
            BufferedImage image = new BufferedImage(wideth, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = image.createGraphics();
            g.drawImage(src, 0, 0, wideth, height, null);

            //水印文件
            File _filebiao = null;
            int wideth_biao = 0;
            int height_biao = 0;
            int x = 0;
            int y = 0;
            for (int i = 0; i < list.size(); i++) {
                Imageftl img = list.get(i);
                _filebiao = new File(img.getUrl());
                Image src_biao = ImageIO.read(_filebiao);
                wideth_biao = src_biao.getWidth(null);
                height_biao = src_biao.getHeight(null);
                x = img.getPrjx();
                y = img.getPrjy();
                g.drawImage(src_biao, x, y, wideth_biao, height_biao, null);
            }
            //水印文件结束
            g.dispose();
            FileOutputStream out = null;
            out = new FileOutputStream(wordspath);

            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(image);
            /** 压缩质量 */
            jep.setQuality(new Float("1.0"), true);
            encoder.encode(image, jep);
            out.close();
        } catch (Exception e) {

            System.out.println(e.getMessage());

        }
    }

    /**
     * 生成二维码
     *
     * @param content 二维码内容
     * @param size    设置设置二维码尺寸，取值范围1-40，值越大尺寸越大，可存储的信息越大
     */
    public static BufferedImage getEwm(String content, int size, String type) {
        try {
            Qrcode handler = new Qrcode();
            // 设置二维码排错率，可选L(7%)、M(15%)、Q(25%)、H(30%)，排错率越高可存储的信息越少，但
            handler.setQrcodeErrorCorrect('M');
            handler.setQrcodeEncodeMode('B');
            // 设置设置二维码尺寸，取值范围1-40，值越大尺寸越大，可存储的信息越大
            handler.setQrcodeVersion(size);

            // 获得内容的字节数组，设置编码格式
            byte[] contentBytes = content.getBytes("UTF-8");

            // 图片尺寸
            int imgSize = 67 + 12 * (size - 1);

            BufferedImage bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);

            Graphics2D gs = bufImg.createGraphics();

            // 设置背景颜色
            gs.setBackground(Color.WHITE);
            gs.clearRect(0, 0, imgSize, imgSize);

            //设定图像颜色：BLACK
            gs.setColor(Color.BLACK);

            //设置偏移量  不设置可能导致解析出错
            int pixoff = 2;
            //输出内容：二维码
            if (contentBytes.length > 0 && contentBytes.length < 800) {
                boolean[][] codeOut = handler.calQrcode(contentBytes);
                for (int i = 0; i < codeOut.length; i++) {
                    for (int j = 0; j < codeOut.length; j++) {
                        if (codeOut[j][i]) {
                            gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
                        }
                    }
                }
            } else {
                System.err.println("QRCode content bytes length = " + contentBytes.length + " not in [ 0,800 ]. ");
            }

            gs.dispose();
            bufImg.flush();
            //重新定义图片大小
            int newimgsize = 0;
            if ("企业".equals(type)) {
                newimgsize = 400;
            } else {
                newimgsize = 200;
            }
            BufferedImage newImg = new BufferedImage(newimgsize, newimgsize, BufferedImage.TYPE_INT_RGB);
            newImg.getGraphics().drawImage(bufImg, 0, 0, newimgsize, newimgsize, null);
            return newImg;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 生成多比例缩略图
     *
     * @param realpath    源图片路径
     * @param standard    生成的尺寸比例多个用逗号分开
     * @param isWaterMark 是否有水印
     */
    public static void doScaleImages(String realpath, String standard, boolean isWaterMark) {
        //读取原图
        File file = new File(realpath);
        //获得文件后缀
        String ext = realpath.substring(realpath.lastIndexOf(".") + 1);
        //获得文件名
        String savepath = realpath.substring(0, realpath.lastIndexOf("."));
        // 生成水印
        if (isWaterMark) {
            //备份原图
            String yl = savepath + "_I." + ext;
            copyTofile(realpath, yl);
            File backUpfile = new File(yl);
            //打上水印
            try {
                //水印
                BufferedImage image = Thumbnailator.createThumbnail(new File(PATH+"upload/logo.png"), 150, 150);
                //水印输出图片
                FileOutputStream out = new FileOutputStream(new File(realpath));
                // 水印位置，水印图片，透明度
                Thumbnails.of(backUpfile).watermark(Positions.BOTTOM_RIGHT, image, 0.5f).outputQuality(0.8f).scale(1).toOutputStream(out);
                //再一次读取加上水印的图片
                file = new File(realpath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        String[] str = standard.split(",");
        int w = 0;
        int h = 0;
        for (int i = 0; i < str.length && StringUtils.isNotBlank(str[i]); i++) {
            //获取图片压缩尺寸
            String[] tg = str[i].split("\\*");
            w = Integer.valueOf(tg[0]);
            h = Integer.valueOf(tg[1]);
            try {
                Thumbnails.of(file).size(w, h).toFile(savepath.replaceAll("=", "_" + w + "x" + h) + "." + ext);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


    }

    /**
     * 复制文件不删除旧文件
     *
     * @param oldPath
     * @param newPath
     */
    public static void copyTofile(String oldPath, String newPath) {
        try {
            File moveFile = new File(oldPath);
            if (moveFile.exists()) {

                File dir = new File(newPath.substring(0, newPath.lastIndexOf(File.separator)));
                // 判断文件夹是否生成
                if (!dir.exists()) {
                    dir.mkdirs();
                }

                // 生成新文件
                File newFile = new File(newPath);

                // 是否存在
                if (!newFile.exists()) {
                    newFile.createNewFile();
                }

                // 取得输入流
                InputStream in = new FileInputStream(oldPath);

                // 指定输出流文件
                FileOutputStream out = new FileOutputStream(newFile);

                int c;
                // 设置缓冲大小
                byte buffer[] = new byte[1024 * 1024 * 2];
                while ((c = in.read(buffer)) != -1) {
                    for (int t = 0; t < c; t++) {
                        out.write(buffer[t]);
                    }

                }

                // 关闭输入，输出流
                in.close();
                out.close();

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

